/*******************************************************************************
 * Copyright (c) 2002 Boris Pruessmann and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v0.5 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation
 ******************************************************************************/
package net.sourceforge.perforce.ui;

import net.sourceforge.perforce.core.ISubmitValidator;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.api.IWhereResult;
import net.sourceforge.perforce.core.internal.api.ChangeSpec;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Display;

import java.util.HashSet;
import java.util.Set;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class WarningErrorSubmitValidator implements ISubmitValidator {
  //----------------------------------------------------------------------------
  // -- Public Methods

  /** @see ISubmitValidator#validateChangeSpec(IPerforceServer, ChangeSpec) */
  public IStatus validateChangeSpec(IPerforceServer server, ChangeSpec changeSpec) {
    IPreferenceStore store = PerforceUIPlugin.getPlugin().getPreferenceStore();
    if (!store.getBoolean(IPerforceUIConstants.PREF_CHECK_CHANGELIST_FOR_WARNINGS_AND_ERROR)) {
      return new Status(Status.OK, PerforceUIPlugin.ID, 0, "", null); //$NON-NLS-1$
    }

    try {
      IWorkspaceRoot root = PerforceUIPlugin.getWorkspace().getRoot();
      Set<IResource> resources = changeSpec.getResources(server, root);

      int errors = 0;
      int warnings = 0;
      for (IResource resource : resources) {
        IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
        for (int i = 0; i < markers.length; i++) {
          Integer severity = (Integer) markers[i].getAttribute(IMarker.SEVERITY);
          switch (severity.intValue()) {
            case IMarker.SEVERITY_ERROR:
              errors++;
              break;

            case IMarker.SEVERITY_WARNING:
              warnings++;
              break;

            default:
              break;
          }
        }
      }

      if (errors > 0 || warnings > 0) {
        final String message =
            "The changelist you are going to submit contains:\n\n" + warnings + " warning(s) and "
                + errors + " error(s).\n\n" + "Do you really want to continue?";

        final Display display = Display.getDefault();
        final boolean[] result = {false};
        display.syncExec(new Runnable() {
          public void run() {
            result[0] =
                MessageDialog.openConfirm(display.getActiveShell(), "Perforce Team Provider",
                    message);
          }
        });

        if (!result[0]) {
          return new Status(Status.ERROR, PerforceUIPlugin.ID, 0,
              "Submit has been aborted by the user.", //$NON-NLS-1$
              null);
        }
      }


      return new Status(Status.OK, PerforceUIPlugin.ID, 0, "", null); //$NON-NLS-1$
    } catch (PerforceException e) {
      return e.getStatus();
    } catch (CoreException e) {
      return e.getStatus();
    }
  }

  // TODO(rcleveng): Remove this?
  @SuppressWarnings("unused")
  private Set<IResource> getResources(IPerforceServer server, ChangeSpec changeSpec,
      IWorkspaceRoot root) throws PerforceException {
    String[] files = changeSpec.getFiles();
    Set<IResource> resources = new HashSet<IResource>();
    for (int i = 0; i < files.length; i++) {
      IWhereResult whereResult = server.where(files[i]);

      Path location = new Path(whereResult.getLocalFilename());
      IResource resource = root.getFileForLocation(location);
      if (resource != null && resource.exists()) {
        resources.add(resource);
      }
    }
    return resources;
  }
}
